﻿using System;
using System.Collections.Generic;
using System.Text;
using DreamShield.Deployment.Assistants.DreamWizard.WizardInterfaces.Bases;
using DreamShield.Deployment.Assistants.DreamWizard;
using DreamShield.Deployment.Installers.DreamPlugins;
using System.Threading;
using DreamShield.Deployment.Installers.DreamWorker;
using System.Windows.Forms;
using DreamShield.Deployment.Driver.Native;

namespace DreamShield.Deployment.Miles.CustomWizard
{
    public class MilesWizardProviderBase : BaseGUICapableWizardInterfaceProvider<IMilesWizardPlugin>
    {
        public static Guid MilesWizardProvider_DefaultPluginsGuid
        {
            get { return new Guid("{EA6485E4-3220-4837-B25B-08C974764F96}"); }
        }

        public override Guid PluginsGuid
        {
            get
            {
                return MilesWizardProvider_DefaultPluginsGuid;
            }
        }

        public MilesWizardProviderBase(DreamWizardEngine engine)
            : base(engine)
        {
            CurrentActionId = WorkerActionId.Custom;

            LoadFromEngine(Engine.WorkerEngine.Plugins);

            /* Charge les plugins */
            #region Plugin
            ExecuteForEachPlugins(new DreamPluggableObject<IMilesWizardPlugin>.ForEachMethodInvoker(delegate(IMilesWizardPlugin actual)
            {
                actual.Load(this);
            }));
            #endregion
        }

        /// <summary>
        /// Thread qui va contenir le processus de configuration.
        /// </summary>
        public virtual Thread WorkingThread { get; protected set; }

        /// <summary>
        /// Mode d'exécution actuel de l'assistant
        /// </summary>
        public virtual WorkerActionId CurrentActionId { get; protected set; }

        /// <summary>
        /// Worker actuel
        /// </summary>
        public virtual IDreamWizardWorker Worker { get; protected set; }

        /// <summary>
        /// Provoque l'annulation, si possible ...
        /// </summary>
        public virtual void Cancel()
        {
            /* pour être sur de ne pas revenir ici */
            Worker.RedefineCustomMode(null);

            /* ben ... on provoque l'annulation ... */
            Cancelled = true;
        }

        /// <summary>
        /// Démarre le processus dans le mode spécifié par actionId dans le thread WorkingThread
        /// et attend pas sa complétion
        /// </summary>
        /// <param name="engine"></param>
        /// <param name="actionId"></param>
        /// <param name="worker"></param>
        /// <returns></returns>
        protected override bool WizardWorkerExecute(DreamWizardEngine engine, WorkerActionId actionId, IDreamWizardWorker worker)
        {
            CurrentActionId = actionId;
            Worker = worker;

            #region Plugin
            ExecuteForEachPlugins(new DreamPluggableObject<IMilesWizardPlugin>.ForEachMethodInvoker(delegate(IMilesWizardPlugin actual)
            {
                actual.WizardWorkerExecute_Begin(engine, actionId, worker);
            }));
            #endregion

            if (actionId == WorkerActionId.Uninstall)
            {
                if (!ConfirmUninstallation())
                    return false;
            }

            MaxCounts.Clear();

            bool result = false;

            WorkingThread = new Thread(new ThreadStart(delegate
            {
                WizardWorkerExecute_ThreadBegin(engine, actionId, worker);
                try
                {
                    result = BaseWizardWorkerExecute(engine, actionId, worker);
                }
                finally
                {
                    WizardWorkerExecute_ThreadEnd(engine, actionId, worker);
                }
            }));
            WorkingThread.Name = "Miles Working Thread";
            WorkingThread.Start();

            Thread.Sleep(100);

            while (!(WorkingThread.ThreadState == ThreadState.Stopped || WorkingThread.ThreadState == ThreadState.Aborted))
            {
                PlatformProvider_Loader.CurrentProvider.UIDoEvents();
                Thread.Sleep(10);
            }

            #region Plugin
            ExecuteForEachPlugins(new DreamPluggableObject<IMilesWizardPlugin>.ForEachMethodInvoker(delegate(IMilesWizardPlugin actual)
            {
                actual.WizardWorkerExecute_End(engine, actionId, worker);
            }));
            #endregion

            return result;
        }

        protected virtual void WizardWorkerExecute_ThreadEnd(DreamWizardEngine engine, WorkerActionId actionId, IDreamWizardWorker worker)
        {
            #region Plugin
            ExecuteForEachPlugins(new DreamPluggableObject<IMilesWizardPlugin>.ForEachMethodInvoker(delegate(IMilesWizardPlugin actual)
            {
                actual.BaseWizardWorkerExecute_ThreadEnd(engine, actionId, worker);
            }));
            #endregion
        }

        protected virtual void WizardWorkerExecute_ThreadBegin(DreamWizardEngine engine, WorkerActionId actionId, IDreamWizardWorker worker)
        {
            #region Plugin
            ExecuteForEachPlugins(new DreamPluggableObject<IMilesWizardPlugin>.ForEachMethodInvoker(delegate(IMilesWizardPlugin actual)
            {
                actual.BaseWizardWorkerExecute_ThreadBegin(engine, actionId, worker);
            }));
            #endregion
        }

        protected virtual bool ConfirmUninstallation()
        {
            string msg = InstallerProvider.GlobalizationService.GetStringFmt("Ready_ConfirmUninstall", false,
                InstallerProvider.Package.ProductName);
            Utils.TraceMessageBox(msg, MessageBoxIcon.Warning);
            if (MessageBox.Show(msg, InstallerProvider.GlobalizationService.GetString("Uninstallation"), MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning) != DialogResult.Yes)
            {
                return false;
            }
            return true;
        }

        protected virtual bool BaseWizardWorkerExecute(DreamWizardEngine engine, WorkerActionId actionId, IDreamWizardWorker worker)
        {
            return base.WizardWorkerExecute(engine, actionId, worker);
        }
    }
}
